#ifndef Utility_String_h
#define Utility_String_h

#include <string>
#include <locale>

#ifndef _T
#ifdef _UNICODE
#define _T(x)  L##x
#else
#define _T(x)  x
#endif
#endif

namespace serika
{
	namespace ut
	{
#ifdef _UNICODE
		typedef wchar_t Char;
		typedef std::wstring String;
#else
		typedef char Char;
		typedef std::string String;
#endif

		struct StringHelper
		{
			static String Convert(const std::string& src, const std::locale& loc = std::locale());
			static String Convert(const char* src, const std::locale& loc = std::locale());
			static String Convert(const std::wstring& src, const std::locale& loc = std::locale());
			static String Convert(const wchar_t* src, const std::locale& loc = std::locale());
			static std::string ToString(const std::wstring& src, const std::locale& loc = std::locale ());
			static std::string ToString (wchar_t const* src, const std::locale& loc = std::locale ());
			static std::wstring ToWString(const std::string& src, const std::locale& loc = std::locale ());
			static std::wstring ToWString(char const* src, const std::locale& loc = std::locale ());

		private:
			static void ClearMbstate (std::mbstate_t& mbs);
			static void ToWStringInternal (std::wstring& outstr, const char* src, size_t size, const std::locale& loc);
			static void ToStringInternal (std::string& outstr, const wchar_t* src, size_t size, const std::locale& loc);
		};

		static const String EMPTY_STRING = _T("");
	}
}

#define STRING(str) serika::ut::String(_T(str));

#ifdef _UNICODE
	#define TO_ASTRING(str) serika::ut::StringHelper::ToString(str)
	#define TO_WSTRING(str) str
#else
	#define TO_WSTRING(str) serika::ut::StringHelper::ToWString(str)
	#define TO_ASTRING(str) str
#endif


#endif
